package com.qf.commons.web.exception;

import com.qf.commons.standar.exception.IExceptionHandler;
import com.qf.data.base.r.Codes;
import com.qf.data.base.r.R;
import com.qf.data.base.r.Rs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.List;

/**
 * description:
 * author: Ken
 * 公众号：Java架构栈
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler implements ResponseBodyAdvice<R> {

    @Autowired(required = false)
    private List<IExceptionHandler> exceptionHandlers;

    /**
     * 统一异常处理 - 处理所有的业务异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R exceptionHandler(Exception e){
        //日志记录
        if (exceptionHandlers != null) {
            //循环执行异常处理器
            for (IExceptionHandler exceptionHandler : exceptionHandlers) {
                //判断是否为匹配的异常
                if(exceptionHandler.isSupport(e)){
                    //当前是需要处理的异常
                    R result = exceptionHandler.exceptionHandler(e);
                    if (result != null) return result;
                }
            }
        }

        log.error("[globl exception] 全局异常触发！", e);
        return Rs.createFail(Codes.FAIL);
    }
    /**
     * 当符合什么条件时，该增强器 触发
     * @param returnType
     * @param converterType
     * @return
             */


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return returnType.getMethod().getReturnType() == R.class;
    }

    @Override
    public R beforeBodyWrite(R r, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (r.getCode() != Codes.SUCC.getCode())
            //修改状态码为500
            response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
        return r;
    }
}
